home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 1 (Walnut Creek)
/
Aminet - June 1993 [Walnut Creek].iso
/
usenet
/
sources
/
volume2
/
sound
/
sendmors.1
Wrap
Text File
|
1988-12-06
|
25KB
|
721 lines
Path: xanth!mcnc!rutgers!mailrus!ulowell!page
From: page@swan.ulowell.edu (Bob Page)
Newsgroups: comp.sources.amiga
Subject: v02i093: sendmorse - morse code generator
Message-ID: <10514@swan.ulowell.edu>
Date: 6 Dec 88 23:00:28 GMT
Organization: University of Lowell, Computer Science Dept.
Lines: 710
Approved: page@swan.ulowell.edu
Submitted-by: joe@dayton.dhdsc.mn.org (Joseph P. Larson)
Posting-number: Volume 2, Issue 93
Archive-name: sound/sendmorse.1
This program converts text files to morse code (out the audio port).
[uuencoded binary included here; it's small. ..Bob]
# This is a shell archive.
# Remove everything above and including the cut line.
# Then run the rest of the file through sh.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar: Shell Archiver
# Run the following text with /bin/sh to create:
# readme
# Makefile
# SendMorse.c
# SendMorse.h
# SendMorse.uu
# This archive created: Tue Dec 6 17:56:12 1988
cat << \SHAR_EOF > readme
SendMorse is a little program I kinda "whipped up" for 2 purposes:
1. Learn more about the audio.device (translate: learn something,
*anything* about the audio.device)
2. Practice my very ailing Morse code.
Thus, here it is in its glorious entirety. (Gag). Note that it's
very heavily based on Rob Peck's "audio.c" from Chapter 8 of his book.
Very heavily.....
For those who think I have a weird Makefile -- not ALL of us can have
hard disks. This make works very quickly as it throws everything into
ram:. Note the odd location of c.lib. I have c32.lib on my SYS1 disk,
so I had to put c.lib on my work disk....
To use it: say "SendMorse [-sendrate] <filelist>". It will send the
files in the file list at the given word rate. Default is 5.
Joe Larson (that's still me -- joe@dayton)
November 12, 1988
Golden Valley, Mn.
-------------------Little Notes Follow Hereafter----------------------
A few little notes concerning timings for those who want to fiddle...
There are a few items that may be worth fiddling with.
1. The wave form. I used a short sine wave sample that took me
about 20 seconds on my calculator. However, it clicks a little
at the start of each dit or dah. I don't know why. I hope
someone tells me.....
2. The MORSE_PERIOD value. This defines the period of the sample.
(See the discussion on the audio.device for a definition of
this.) Higher values mean lower frequency.
3. The calculations for ditlength, ditcycles and dahcycles. I
decided that I didn't want longer dits and dahs at slower speeds
but would just add more spacing between letters and words. Thus,
ditcycles is a constant and dahcycles is 3*ditcycles. You may
want to fiddle with these, but I think it works out well.
Ditlength, though, was originally how long a dit was supposed
to be. And I was using a ditlength pause between dits and
dahs and 3*ditlength between letters. I have a constant defined
somewhere that is the number of ditlengths between words (currently
6). This item is in 20 millisecond increments, as that's what
the Delay() function *seems* to use.
Because of all this, the sendrate appears to be maybe a little
higher than you ask for. That is, the default of 5 WPM on a 20
character sample SHOULD take about 48 seconds but seems to be a
little closer to 35 or 40. You can add a little fudge factor
if you like -- I'm not too concerned about it.....
4. Channel allocation. I only use one channel. I should probably
have used Rob's "GetAnyStereoPair" rather than just grabbing
a single channel, but that's the way it goes.
SHAR_EOF
cat << \SHAR_EOF > Makefile
SendMorse: ram:SendMorse
copy ram:SendMorse SendMorse
ram:SendMorse.o: SendMorse.c SendMorse.h
make ram:SendMorse.c
make ram:SendMorse.syms
cc +Iram:SendMorse.syms ram:SendMorse.c
copy ram:SendMorse.o SendMorse.o
ram:SendMorse.c: SendMorse.c
copy SendMorse.c ram:
ram:SendMorse.syms: SendMorse.h
cc +Hram:SendMorse.syms SendMorse.h
copy ram:SendMorse.syms SendMorse.syms
ram:SendMorse: ram:SendMorse.o
make ram:c.lib
ln -o ram:SendMorse ram:SendMorse.o -lram:c
ram:c.lib: df1:lib/c.lib
copy df1:lib/c.lib ram:
SHAR_EOF
cat << \SHAR_EOF > SendMorse.c
#include "SendMorse.h"
#define MORSE_C1000 3579
#define MORSE_PERIOD 500
#define MORSE_LENGTH 6
#define MORSE_SPACE 6 /* # of dits between words */
BYTE sinewave[8] = {0, 90, 127, 90, 0, -90, -127, -90};
struct Device *auDevice=0;
struct IOAudio *audioIOB;
struct IOAudio *aulockIOB;
struct IOAudio *aufreeIOB;
BYTE *chipaudio = 0;
struct MsgPort *auReplyPort, *auLockPort;
extern UBYTE *AllocMem();
extern struct MsgPort *CreatePort();
struct IOAudio *CreateAudioIO();
UBYTE GetAnyChannel();
void FreeAudioIO();
#define isalpha(c) (((c>='a') && (c<='z')) || ((c>='A') && (c<='Z')))
#define isdigit(c) ((c >= '0') && (c <= '9'))
long sendrate = 5, ditcycles, dahcycles, ditlength;
main(argc,argv)
int argc;
char **argv;
{
short i;
GetSoundStuff();
for (i = 1; i < argc; i++)
{
if (*argv[i] == '-')
{
sendrate = atoi(argv[i]+1);
if (sendrate <= 0)
finishup("usage: code [-sendrate] <filelist>");
}
else
Work(argv[i]);
}
FreeAChannel(aufreeIOB);
finishup("all done");
}
GetSoundStuff()
{
int i;
UBYTE chan;
audioIOB = CreateAudioIO();
aulockIOB = CreateAudioIO();
aufreeIOB = CreateAudioIO();
if(audioIOB == 0 || aufreeIOB == 0 | aulockIOB == 0)
finishup("out of memory!");
if ((chipaudio = (BYTE *)AllocMem(8L, MEMF_CHIP)) == 0)
finishup("out of memory!");
for (i = 0; i < 8; i++)
chipaudio[i] = sinewave[i];
if (OpenDevice("audio.device",0L,audioIOB,0L))
finishup ("audio device won't open!");
/* Get the device address for later use */
auDevice = audioIOB->ioa_Request.io_Device;
/* Create ports for replies from the device */
auReplyPort = CreatePort(0L,0L);
auLockPort = CreatePort(0L,0L);
if(auReplyPort == 0 || auLockPort == 0)
finishup("cannot create a port!");
/*
* initialize port addresses and device fields
* for all audio request blocks
*/
audioIOB->ioa_Request.io_Device = auDevice;
aulockIOB->ioa_Request.io_Device = auDevice;
audioIOB->ioa_Request.io_Message.mn_ReplyPort = auReplyPort;
aulockIOB->ioa_Request.io_Message.mn_ReplyPort = auLockPort;
chan = GetAnyChannel(audioIOB);
/* Make the allocation keys match */
aulockIOB->ioa_AllocKey = audioIOB->ioa_AllocKey;
/* Make the unit numbers match */
aulockIOB->ioa_Request.io_Unit = audioIOB->ioa_Request.io_Unit;
LockAChannel(aulockIOB,chan);
/*
* If checkio returns true, it means the request has
* been returned. This means the channel has been
* stolen.
*/
if(CheckIO(aulockIOB))
finishup("A channel was stolen!");
/*
* now assuming nothing stolen, setup and request
* an output from that channel.
*/
audioIOB->ioa_Data = (UBYTE *)chipaudio;
audioIOB->ioa_Length = 8/2; /* 4 WORDS in table */
audioIOB->ioa_Period = MORSE_PERIOD; /* from table */
audioIOB->ioa_Volume = 64; /* maximum */
audioIOB->ioa_Cycles = 1000; /* # of times */
audioIOB->ioa_Request.io_Command = CMD_WRITE;
audioIOB->ioa_Request.io_Flags = ADIOF_PERVOL;
/* copy the audio block for freeing channels later */
*aufreeIOB = *audioIOB;
}
finishup(string)
char *string;
{
if(auDevice) CloseDevice(audioIOB);
if(chipaudio) FreeMem(chipaudio,8L);
if(audioIOB) FreeAudioIO(audioIOB);
if(aulockIOB) FreeAudioIO(aulockIOB);
if(auReplyPort) DeletePort(auReplyPort);
if(auLockPort) DeletePort(auLockPort);
printf("%ls\n",string);
exit(0);
}
/* newaudioblock.c */
struct IOAudio *
CreateAudioIO()
{
struct IOAudio *iob;
iob = (struct IOAudio *) AllocMem((long)sizeof(struct IOAudio),
MEMF_CHIP | MEMF_CLEAR);
return(iob); /* returns 0 if out of memory */
}
void
FreeAudioIO(iob)
struct IOAudio *iob;
{
FreeMem(iob, (long)sizeof(struct IOAudio));
}
/* lockachannel.c */
LockAChannel(lockiob,channel)
struct IOAudio *lockiob;
UBYTE channel;
{
/* tell it which channel to lock */
/* lockiob->ioa_Request.io_Unit = (struct Unit *)channel; */
lockiob->ioa_Request.io_Command = ADCMD_LOCK;
lockiob->ioa_Request.io_Flags = 0;
/* Send this command. It does not return to
* the reply port unless and until either this
* task frees the channel or another channel of
* higher precedence steals it. Appropriate
* to keep two reply ports, perhaps... one for
* standard I/O replies, other for channel steal
* requests.
*/
BeginIO(lockiob);
}
FreeAChannel(iob)
struct IOAudio *iob;
{
/* allocation key and unit number must already be valid */
iob->ioa_Request.io_Command = ADCMD_FREE;
iob->ioa_Request.io_Flags = IOF_QUICK;
BeginIO(iob);
WaitIO(iob);
}
/* getaudio.c */
UBYTE
GetAnyChannel(iob)
struct IOAudio *iob;
{
UBYTE anychan[4];
UBYTE mychan;
int error;
anychan[0] = 1;
anychan[1] = 2;
anychan[2] = 4;
anychan[3] = 8;
iob->ioa_Request.io_Message.mn_Node.ln_Pri = 20;
iob->ioa_Request.io_Command = ADCMD_ALLOCATE;
iob->ioa_Data = (UBYTE *)anychan;
iob->ioa_Length = 4;
iob->ioa_Request.io_Flags = ADIOF_NOWAIT | IOF_QUICK;
BeginIO(iob);
error = WaitIO(iob); /* returns nonzero if error */
if(!(iob->ioa_Request.io_Flags & IOF_QUICK))
GetMsg(iob->ioa_Request.io_Message.mn_ReplyPort);
if(error)
return(0);
mychan = ((ULONG)(iob->ioa_Request.io_Unit)) & 0xFF;
return(mychan);
}
#define MAX_LETTERS 47
char *letters[MAX_LETTERS] =
{
".-", /* A */
"-...", /* B */
"-.-.", /* C */
"-..", /* D */
".", /* E */
"..-.", /* F */
"--.", /* G */
"....", /* H */
"..", /* I */
".---", /* J */
"-.-", /* K */
".-..", /* L */
"--", /* M */
"-.", /* N */
"---", /* O */
".--.", /* P */
"--.-", /* Q */
".-.", /* R */
"...", /* S */
"-", /* T */
"..-", /* U */
"...-", /* V */
".--", /* W */
"-..-", /* X */
"-.--", /* Y */
"--..", /* Z */
"-----", /* 0 */
".----", /* 1 */
"..---", /* 2 */
"...--", /* 3 */
"....-", /* 4 */
".....", /* 5 */
"-....", /* 6 */
"--...", /* 7 */
"---..", /* 8 */
"----.", /* 9 */
"--..--", /* , */
".-.-.-", /* . */
"..--..", /* ? */
"-.-.-.", /* ; */
"---...", /* : */
"-..-.", /* / */
"-....-", /* - */
".----.", /* ' */
"-.--.-", /* () */
"..--.-", /* _ */
};
Work(fname)
char *fname;
/*
* Get strings and send them to the audio port.
*
* Dlen: 1000 millis/sec * 1/8 chars/dit * 1/25 min/chars * 1/60 secs/min
*/
{
char *cptr, line[132];
FILE *file;
if ((file = fopen(fname, "r")) == NULL)
finishup("can't open a file");
ditlength = 75 / sendrate; /* In 20 milliseconds */
ditcycles = 12 * (MORSE_C1000 / MORSE_PERIOD);
dahcycles = ditcycles * 3;
while (fgets(line, 132, file))
{
for (cptr = line; *cptr && (*cptr != '\n'); cptr++)
{
SendLetter(*cptr);
PauseDit(3);
}
}
fclose(file);
}
SendLetter(c)
char c;
/*
* Send character c.
*/
{
char *cptr, *temp = ",.?;:;/-,{}_", *findchar();
short i;
if (c == ' ')
{
PauseDit(MORSE_SPACE);
return;
}
if (isalpha(c))
c = tolower(c) - 'a';
else if (isdigit(c))
c = c - 'a' + 26;
else
{
cptr = findchar(temp, c);
c = 37 + cptr - temp;
}
cptr = letters[c];
i = 0;
for ( ; *cptr != 0; cptr++, i++)
{
if (i)
PauseDit(1);
/*
* We'll send each dit or dah. We know it's done when WaitIO
* returns. I think.
*/
if (*cptr == '.')
audioIOB->ioa_Cycles = ditcycles;
else
audioIOB->ioa_Cycles = dahcycles;
BeginIO(audioIOB);
WaitIO(audioIOB);
}
}
char *findchar(s,c)
char *s,c;
{
for ( ; *s; s++)
if (*s == c)
return(s);
return(NULL);
}
PauseDit(ditcount)
short ditcount;
/*
* Pause for ditcount dit periods.
*
* Do this by setting the timer and waiting for it.
*/
{
Delay((long)(ditcount * ditlength));
}
SHAR_EOF
cat << \SHAR_EOF > SendMorse.h
#include "stdio.h"
#include "exec/types.h"
#include "exec/memory.h"
#include "devices/audio.h"
SHAR_EOF
cat << \SHAR_EOF > SendMorse.uu
begin 644 SendMorse
M```#\P`````````#``````````(```>K````[@````$```/I```'JT[Z"G9.0
M5?_^3KH`NCM\``'__F!B,"W__DC`Y8`@;0`*(G`(``P1`"UF,C`M__Y(P.6`L
M(&T`"B)P"`!2B2\)3KH'>%A/2,`I0(`22JR`$FX*2'H`1DZZ`J!83V`6,"W_@
M_DC`Y8`@;0`*+S`(`$ZZ!2Q83U)M__XP+?_^L&T`"&V4+RR#GDZZ`TY83TAZ#
M`"].N@)F6$].74YU=7-A9V4Z(&-O9&4@6RUS96YD<F%T95T@/&9I;&5L:7-T1
M/@!A;&P@9&]N90!.5?_\3KH"L"E`@Y9.N@*H*4"#FDZZ`J`I0(.>2JR#EF<<5
M2JR#GF8$<`%@`G``2JR#FF8$<@%@`G(`@$%G"DAZ`8).N@'N6$](>``"2'@`?
M"$ZZ')Y03RE`@`YF"DAZ`7-.N@'06$]";?_^,"W__D'L@`(R+?_^(FR`#A.PV
M```0`%)M__X,;0`(__YMWD*G+RR#ED*G2'H!2DZZ',)/[P`02D!G"DAZ`4=.O
MN@&(6$\@;(.6*6@`%(`*0J="ITZZ&TA03RE`@Z)"IT*G3KH;.E!/*4"#IDJL^
M@Z)G!DJL@Z9F"DAZ`21.N@%,6$\@;(.6(6R`"@`4(&R#FB%L@`H`%"!L@Y8AN
M;(.B``X@;(.:(6R#I@`.+RR#EDZZ`BA83QM`__T@;(.6(FR#FC-H`"``("!LG
M@Y8B;(.:(V@`&``8<``0+?_]/P`O+(.:3KH!HEQ/+RR#FDZZ&HI83TI`9PI(#
M>@"^3KH`T%A/(&R#EB%L@`X`(B!L@Y8A?`````0`)B!L@Y8Q?`'T`"H@;(.6;
M,7P`0``L(&R#EC%\`^@`+B!L@Y8Q?``#`!P@;(.6$7P`$``>(&R#GB)L@Y9P9
M$"#94<C__$Y=3G5O=70@;V8@;65M;W)Y(0!O=70@;V8@;65M;W)Y(0!A=61I\
M;RYD979I8V4`875D:6\@9&5V:6-E('=O;B=T(&]P96XA`&-A;FYO="!C<F5AO
M=&4@82!P;W)T(0!!(&-H86YN96P@=V%S('-T;VQE;B$`3E4``$JL@`IG"B\L*
M@Y9.NAFH6$]*K(`.9PY(>``(+RR`#DZZ&L103TJL@Y9G""\L@Y9A<%A/2JR#;
MFF<(+RR#FF%B6$]*K(.B9PHO+(.B3KH:$%A/2JR#IF<*+RR#IDZZ&@!83R\M)
M``A(>@`43KH-NE!/0F=.NA<25$].74YU)6QS"@``3E7__$AY``$``DAX`$1.Y
MNAHJ4$\K0/_\("W__$Y=3G5.50``2'@`1"\M``A.NAHV4$].74YU3E4``"!M9
M``@Q?``-`!P@;0`(0B@`'B\M``A.NAC*6$].74YU3E4``"!M``@Q?``)`!P@(
M;0`($7P``0`>+RT`"$ZZ&*183R\M``A.NAIP6$].74YU3E7_^!M\``'__!M\_
M``+__1M\``3__AM\``C__R!M``@1?``4``D@;0`(,7P`(``<0>W__")M``@C3
M2``B(&T`""%\````!``F(&T`"!%\`$$`'B\M``A.NA@Z6$\O+0`(3KH:!EA/?
M.T#_^"!M``@(*````!YF#B!M``@O*``.3KH9>EA/2FW_^&<&<`!.74YU(&T`+
M""`H`!C`O````/\;0/_[$"W_^V#D+BT`+2XN+@`M+BTN`"TN+@`N`"XN+2X`I
M+2TN`"XN+BX`+BX`+BTM+0`M+BT`+BTN+@`M+0`M+@`M+2T`+BTM+@`M+2XMW
M`"XM+@`N+BX`+0`N+BT`+BXN+0`N+2T`+2XN+0`M+BTM`"TM+BX`+2TM+2T`*
M+BTM+2T`+BXM+2T`+BXN+2T`+BXN+BT`+BXN+BX`+2XN+BX`+2TN+BX`+2TM$
M+BX`+2TM+2X`+2TN+BTM`"XM+BTN+0`N+BTM+BX`+2XM+BTN`"TM+2XN+@`M`
M+BXM+@`M+BXN+BT`+BTM+2TN`"TN+2TN+0`N+BTM+BT``$Y5_W1(>@"@+RT`.
M"$ZZ!#103RM`_W1F"DAZ`(Y.NOT^6$\B+(`2<$M.N@\>*4"#LBE\````5(.J#
M<@,@+(.J3KH*;"E`@ZXO+?]T/SP`A$AM_WA.N@)L3^\`"DI`9SI![?]X*TC_`
M_&`<(&W__!`02(`_`&%&5$\_/``#3KH!A%1/4JW__"!M__Q*$&<*(FW__`P13
M``IFTF"N+RW_=$ZZ$"!83TY=3G5R`&-A;B=T(&]P96X@82!F:6QE`$Y5__9!7
M^@$(*TC_^`PM`"``"68./SP`!DZZ`2Q43TY=3G4,+0!A``EM"`PM`'H`"6\0=
M#"T`00`);2`,+0!:``EN&!`M``E(@#\`3KH!HE1/D'P`81M```E@0@PM`#``I
M"6T0#"T`.0`);@@$+0!'``E@*A`M``E(@#\`+RW_^$ZZ`)Q<3RM`__P@;?_\?
MT?P````ED>W_^#`(&T``"1`M``E(@$C`Y8!![(`6*W`(`/_\0FW_]F!,2FW_E
M]F<*/SP``4ZZ`(143R!M__P,$``N9@P@;(.6,6R#K``N8`H@;(.6,6R#L``N"
M+RR#EDZZ%5983R\L@Y9.NA<B6$]2K?_\4FW_]B!M__Q*$&:L8`#_$BPN/SLZ+
M.R\M+'M]7P``3E4``&`8(&T`"!`0L"T`#68(("T`"$Y=3G52K0`((&T`"$H0[
M9N!P`&#L3E4``#`M``A(P"(L@[).N@B<+P!.NA1`6$].74YU3E4``$CG#"`D#
M;0`(#!(`(&<&#!(`"68$4HI@\'H`#!(`+68&>@%2BF`(#!(`*V8"4HIX`&`6(
M($I2BA`02(`R!,+\``K003@`F'P`,!`22(!20$'L@1H(,``"``!FV$I%9P8PA
M!$1`8`(P!$S?!#!.74YU<``0+P`%L#P`8&,*L#P`>F($D#P`($YU<``0+P`%'
ML#P`0&,*L#P`6F($T#P`($YU3E4``$CG""`D;0`(4VT`#$IM``QO("\M``Y.=
MN@`X6$\X`+!\__]G#B!*4HH0A+A\``IG`F#60A*X?/__9A"U[0`(9@IP`$S?8
M!!!.74YU("T`"&#R3E4``$CG""`D;0`(+PI.N@`R6$\X`+!\__]G(C`$2,!@=
M%%.2".H``P`,</],WP003EU.=6#62H!G^EF`9^0P!&#J3E4``"\*)&T`""!2`
ML>H`!&4,+PIA%EA/)%].74YU(%)2DA`02(#`?`#_8.Q.50``2.<(,"1M``@00
M*@`,P#P`&&<*</],WPP03EU.=0BJ``(`#$JJ``AF""\*3KH.K%A/$"H`#$B`Y
M"```!V<P0>R!G"9($"L`#$B`P'P`A+!\`(1F##\\__\O"TZZ#61<3]?\````Y
M%D'L@U2WR&76/RH`$"\J``@0*@`-2(`_`$ZZ!;Q03S@`2D!N%$I$9@1P"&`"Z
M<!"!*@`,</]@`/]Z,`1(P"2J``C0J@`()4``!"!24I(0$$B`P'P`_V``_UI.\
M50``+PI.N@W<)$!*@&8(<``D7TY=3G4O"B\M``PO+0`(809/[P`,8.A.50``=
M2.<(("\M`!!.N@Q$6$]![(#2)$A*$F80.7P`!8-:<`!,WP003EU.=2\M``PO*
M"DZZ!<Q03TI`9P1<BF#8/RH`!"\M``A.N@.^7$\X`+!\__]F!'``8,H@;0`0=
M$40`#2!M`!`1?``!``P@+0`08+)A<$/L@U9%[(-6M<EF#C(\`!AK"'0`(L)1_
MR?_\*4^#7"QX``0I3H-@2.>`@`@N``0!*6<02_H`"$ZN_^)@!D*G\U].<T/ZP
M`"!.KOYH*4"#9&8,+CP``X`'3J[_E&`$3KH`&E!/3G5D;W,N;&EB<F%R>0!)A
M^0``?_Y.=4Y5```O"DAY``$``#`L@U3!_``&+P!.NA*N4$\I0(-H9A1"ITAY;
M``$``$ZZ$6!03RYL@UQ.=2!L@VA":``$(&R#:#%\``$`$")L@V@S?``!``H@"
M;(-<("R#7)"H``10@"E`@VP@;(-L(+Q-04Y80J=.NA)F6$\D0$JJ`*QG+B\MJ
M``PO+0`(+PI.N@"R3^\`##E\``&#<"!L@V@`:(````0@;(-H`&B````*8$1(.
M:@!<3KH2U%A/2&H`7$ZZ$E183RE`@W(@;(-R2J@`)&<0(&R#<B)H`"0O$4ZZA
M$!A83R\L@W(O"DZZ!))03REL@W*#=DZZ$"0@;(-H((!.NA!2(&R#:"%```9G:
M%DAX`^U(>@`L3KH0+E!/(&R#:"%```PO+(-V/RR#>DZZ\^I<3T)G3KH.7%1/'
M)%].74YU*@!.50``2.<,,"1M`!`@;0`(("@`K.6`*``@1"`H`!#E@"9`$!-(2
M@$C`T*T`#%2`.4"#?$*G,"R#?$C`+P!.NA%,4$\I0(-^9@A,WPPP3EU.=1`3L
M2(`_`"!+4H@O""\L@WY.N@%$3^\`"DAZ`3H0$TB`2,#0K(-^+P!.N@..4$\_'
M+0`.+PHO+(-^3KH#*D_O``I";(-Z)FR#?B1+$!-(@#H`L'P`(&<8NGP`"6<2B
MNGP`#&<,NGP`#6<&NGP`"F8$4HM@V`P3`"!M>@P3`")F+E*+($M2BQ`02(`ZF
M`&<>($I2BA"%NGP`(F80#!,`(F8$4HM@!D(J__]@`F#68#@@2U*+$!!(@#H`@
M9R:Z?``@9R"Z?``)9QJZ?``,9Q2Z?``-9PZZ?``*9P@@2E**$(5@SB!*4HI"?
M$$I%9@)3BU)L@WI@`/]:0A)"IS`L@WI20$C`Y8`O`$ZZ$#903RE`@W9F"$)L(
M@WI@`/[D>@`F;(-^8!XP!4C`Y8`@;(-V(8L(`"\+3KH'W%A/4D!(P-?`4D6ZS
M;(-Z;=PP!4C`Y8`@;(-V0K`(`&``_J8@`$SO`P``!"`(,B\`#&`"$-E7R?_\T
M9P9206`"0AA1R?_\3G5.50``/RT`##\\`P$O+0`(80903TY=3G5.50``2.</G
M,"1M``A.N@P&)FR#:'@`8`XP!,'\``9*LP@`9PY21+AL@U1M['H&8```R@@M`
M``$`#&<R2'C__R\*3KH-U%!/+`!G(B\&3KH."%A/+PI.N@V86$]*@&8.3KH-T
MHCH`L'P`S68``)!(>`/M+PI.N@VP4$\L`$J&9F0(+0````QF!'H!8'!(>`/N%
M+PI.N@V24$\L`&8(3KH-9CH`8%A(>``A2'H`EDZZ#WQ03RX`9PHO!TZZ#?A8K
M3V`B2'@``4AZ`(8O!DZZ#9A/[P`,2'C__T*G+P9.N@UN3^\`#&`F,"T`#,!\:
M!0"P?`4`9A@O!DZZ#-983WH$.46#6G#_3-\,\$Y=3G4P!,'\``8GA@@`,`3!X
M_``&($#1RS%M``P`!`@M``,`#&<02'@``4*G+P9.N@T43^\`##`$8,)D;W,N#
M;&EB<F%R>0```$Y5``!(YPP@."T`"$ZZ"KHP!,'\``8D0-7L@VA*1&T*N&R#?
M5&P$2I)F$#E\``*#6G#_3-\$,$Y=3G4P*@`$P'P``[!\``%F"CE\``6#6G#_F
M8.!P`#`M``XO`"\M``HO$DZZ#(Q/[P`,*@"PO/____]F#$ZZ#$(Y0(-:</]@:
MM"`%8+`P/'__8`0P+P`,(&\`!$H89OQ32")O``A30!#95\C__&<"0A`@+P`$1
M3G4P/'__8`0P+P`,4T!K%"!O``0B;P`(L0EF#%-(2AA7R/_V<`!.=6,$<`%.0
M=7#_3G4@;P`$(`@B;P`($-EF_$YU2.=P`#0!Q,`F`4A#QL!(0T)#U(-(0,#!)
M2$!"0-""3-\`#DYU3E4``$CG#C`D;0`(0J=(>@".3KH-N%!/*4"#MF8(3-\,M
M<$Y=3G4@;0`,(F@`)"\I``1.N@X`6$\H`&=22'H`;2!$+R@`-DZZ#=)03R9`K
M2H!G-$AX`^TO"TZZ"VY03RP`9R0@!N6`*@`@125H``@`I"5&`)Q(>`/M2'H`R
M.$ZZ"TI03R5``*`O!$ZZ#9Y83R\L@[9.N@N\6$]"K(.V8(!I8V]N+FQI8G)AX
M<GD`5TE.1$]7`"H`3E4``$AM``PO+0`(2'H$<$ZZ`)A/[P`,3EU.=4Y5``!(N
MYP@@)&T`#@QM``0`$F8((&T`""@08!Q*;0`,;PP@;0`(<``P$"@`8`H@;0`(>
M,!!(P"@`0FT`$DIM``QL$$1M``Q*A&P(1(0[?``!`!(R+0`,2,$@!$ZZ`XY!S
M[($(4XH4L```,BT`#$C!(`1.N@.$*`!FVDIM`!)G!E.*%+P`+2`*3-\$$$Y=)
M3G5.5?\B2.<(,"1M``@F;0`,0FW_^BMM`!#__"!+4HL0$$B`.`!G``+LN'P`B
M)68``LI"+?\P.WP``?_X.WP`(/_V.WPG$/_T($M2BQ`02(`X`+!\`"UF#D)MU
M__@@2U*+$!!(@#@`N'P`,&80.WP`,/_V($M2BQ`02(`X`+A\`"IF&"!M__Q4U
MK?_\.U#_\B!+4HL0$$B`.`!@,D)M__)@'#`M__+!_``*T$20?``P.T#_\B!+V
M4HL0$$B`.``P!%)`0>R!&@@P``(``&;4N'P`+F9:($M2BQ`02(`X`+!\`"IF%
M&"!M__Q4K?_\.U#_]"!+4HL0$$B`.`!@,D)M__1@'#`M__3!_``*T$20?``P9
M.T#_]"!+4HL0$$B`.``P!%)`0>R!&@@P``(``&;4.WP``O_PN'P`;&82($M25
MBQ`02(`X`#M\``3_\&`0N'P`:&8*($M2BQ`02(`X`#`$2,!@>#M\``C_[F`6O
M.WP`"O_N8`X[?``0_^Y@!CM\__;_[C\M__!(;?\P/RW_[B\M__Q.NOWD3^\`E
M#"M`_^HP+?_P2,#1K?_\8%H@;?_\6*W__"M0_^HO+?_J3KH"#%A/.T#_\&!*I
M(&W__%2M__PX$$'M_R\K2/_J$(1@*)"\````8V?B4X!GE)"\````"V<`_W19P
M@&>T58!G`/]R5X!G`/]T8,Q![?\PD>W_ZCM(__`P+?_PL&W_]&\&.VW_]/_PV
M2FW_^&=H(&W_Z@P0`"UG"B)M_^H,$0`K9BX,;0`P__9F)E-M__(@;?_J4JW_0
MZA`02(`_`$Z25$^P?/__9@IP_TS?#!!.74YU8!8_+?_V3I)43[!\__]F!'#_O
M8.12;?_Z,"W_\E-M__*P;?_P;MQ";?_N8"`@;?_J4JW_ZA`02(`_`$Z25$^PE
M?/__9@1P_V"P4FW_[B!M_^I*$&<*,"W_[K!M__1MSC`M_^[1;?_Z2FW_^&8HB
M8!@_/``@3I)43[!\__]F!G#_8`#_>%)M__HP+?_R4VW_\K!M__!NVF`6/P1.$
MDE1/L'S__V8&</]@`/]24FW_^F``_0HP+?_Z8`#_0DCG2`!"A$J`:@1$@%)$0
M2H%J!D2!"D0``6$^2D1G`D2`3-\`$DJ`3G5(YT@`0H1*@&H$1(!21$J!:@)$]
M@6$:(`%@V"\!81(@`2(?2H!.=2\!808B'TJ`3G5(YS``2$%*068@2$$V`30`Y
M0D!(0(##(@!(0#("@L,P`4)!2$%,WP`,3G5(028!(@!"04A!2$!"0'0/T(#3U
M@;:!8@22@U)`4<K_\DS?``Q.=2!O``0@"$H89OR1P"`(4X!.=4Y5``!(;(&RC
M/RT`"$ZZ``A<3TY=3G5.50``+P0X+0`(+RT`"C\$3KH`,%Q/N'P`"F8D(&T`!
M"A`H``Q(@`@```=G%#\\__\O+0`*3KH`]EQ/*!].74YU8/A.50``+PHD;0`*L
M(%*QZ@`$91@P+0`(P'P`_S\`+PI.N@#*7$\D7TY=3G4@4E*2$"T`"1"`2(#`(
M?`#_8.A.50``+PI![(&<)$@@2M7\````%B\(81!83T'L@U2UR&7J)%].74YUV
M3E4``$CG""`D;0`(>``@"F8*</],WP003EU.=4HJ``QG4@@J``(`#&<,/SS_G
M_R\*851<3S@`$"H`#4B`/P!.N@3R5$^(0`@J``$`#&<*+RH`"$ZZ`C!83P@JK
M``4`#&<4+RH`$DZZ`L)83R\J`!).N@(46$]"DD*J``1"J@`(0BH`##`$8(Y.Z
M5?_^2.<(("1M``A!^O]$*4B#@@@J``0`#&<*</],WP003EU.=0@J``(`#&<P<
M(!*0J@`(.``_!"\J``@0*@`-2(`_`$ZZ`H!03[!$9Q`(Z@`$``Q"DD*J``1PH
M_V#`#&W__P`,9A`(J@`"``Q"DD*J``1P`&"H2JH`"&8(+PI.N@":6$\,:@`!W
M`!!F*AMM``W__S\\``%(;?__$"H`#4B`/P!.N@(B4$^P?``!9J`P+0`,8`#_V
M:B2J``@P*@`02,#0J@`()4``!`CJ``(`#"!24I(0+0`-$(!(@,!\`/]@`/\^M
M3E4``"\*0>R!G"1(2BH`#&<8U?P````60>R#5+7(90AP`"1?3EU.=6#B0I)"?
MJ@`$0JH`""`*8.I.5?_\+PHD;0`(/SP$`$ZZ`,!43RM`__QF\``$`$"`*`
MT+P````.)4``""1?3EU.=35\!```$`CJ``$`#"5M__P`"!`J``U(@#\`3KH`G
MXE1/2D!G!@`J`(``#&#.3E4``$CG`#`D;(-68!0F4B`J``10@"\`+PI.N@5PZ
M4$\D2R`*9NA"K(-63-\,`$Y=3G5.50``+PI!^O_&*4B#AD*G("T`"%"`+P!.3
MN@464$\D0$J`9@AP`"1?3EU.=22L@U8E;0`(``0I2H-6(`I0@&#F3E4``'``7
M,"T`""\`8;)83TY=3G5.50``2.<`,)?+)&R#5F`.(&T`"%&(L<IG$B9*)%(@?
M"F;N</],WPP`3EU.=2`+9P0FDF`$*5*#5B`J``10@"\`+PI.N@3"4$]P`S
M3E4``"\*,"T`",'\``8D0-7L@VA*;0`(;0XP+0`(L&R#5&P$2I)F#CE\``*#@
M6G#_)%].74YU,"T`",'\``8@;(-H+S`(`$ZZ`JA83TJ`9P1P`6`"<`!@V$Y5L
M```O+0`(3KH"<EA/2H!F#DZZ`GPY0(-:</].74YU<`!@^$Y5``!(YPP@."T`I
M"$ZZ`'`P!,'\``8D0-7L@VA*1&T*N&R#5&P$2I)F$#E\``*#6G#_3-\$,$Y=6
M3G4P*@`$P'P``V8*.7P`!8-:</]@Y'``,"T`#B\`+RT`"B\23KH";D_O``PJW
M`+"\_____V8,3KH!_#E`@UIP_V"X(`5@M$Y5__Q(>!``0J=.N@0P4$\K0/_\-
M"```#&<22FR#<&8(("W__$Y=3G5.N@`&<`!@]$Y5``!(>``$2'H`'DZZ`>`O+
M`$ZZ`@I/[P`,/SP``4ZZ``Q43TY=3G5>0PH`3E4``$JL@X)G!B!L@X).D#\M0
M``A.N@`(5$].74YU3E7__"\$,"T`"$C`*T#__$JL@VAG*'@`8`H_!$ZZ`-!4.
M3U)$N&R#5&WP,"R#5,'\``8O`"\L@VA.N@,,4$]*K(.&9P8@;(.&3I!*K(.*`
M9PHO+(.*3KH!S%A/2JR#CF<*+RR#CDZZ`;Q83TJL@Y)G"B\L@Y).N@&L6$\L9
M>``$""X`!`$I9Q0O#4OZ``I.KO_B*E]@!D*G\U].<TJL@W)F,$JL@WYG*#`L1
M@WQ(P"\`+RR#?DZZ`I)03S`L@WI20$C`Y8`O`"\L@W9.N@)\4$]@#DZZ`F@O<
M+(-R3KH"W%A/("W__"YL@UQ.=2@?3EU.=4Y5``!(YPX@."T`"#`$P?P`!B1`O
MU>R#:$I$;0JX;(-4;`1*DF80.7P``H-:</],WP1P3EU.=3`J``3`?(``9@@OU
M$DZZ``I83T*2<`!@X"(O``0L;(-D3N[_W"(O``0L;(-D3N[_@B(O``0L;(-D?
M3N[_.B(O``0L;(-D3N[_N"QL@V1.[O_*+&R#9$[N_WPB+P`$+&R#9$[N_RA,Y
M[P`&``0L;(-D3N[_K$SO``8`!"QL@V1.[O_B+&R#9$[N_\1,[P`.``0L;(-D*
M3N[_UDSO``X`!"QL@V1.[O^^(B\`!"QL@V1.[O^F3.\`#@`$+&R#9$[N_]!(J
MYP$$3.\@@``,+&R#8$ZN_Y1,WR"`3G4B;P`$+&D`%$[N_^(B;P`$+&R#8$[N2
M_BPB;P`$+&R#8$[N_CY.^@`"(F\`!"QL@V!.[OYB3E4``$CG""!(>/__3KH`H
MT%A/*`"PO/____]F"G``3-\$$$Y=3G5(>0`!``%(>``B3KH`N%!/)$!*@&8,X
M+P1.N@#H6$]P`)6T`"``*%6T`#P`)%7P`!``(0BH`#A5$``]"ITZZ`)98,
M3R5``!!*K0`(9PHO"DZZ`%I83V`*2&H`%$ZZ`,!83R`*8)).50``+PHD;0`(F
M2JH`"F<(+PI.N@#<6$\5?`#_``@E?/____\`%'``$"H`#R\`3KH`;%A/2'@`]
M(B\*3KH`3%!/)%].74YU(F\`!"QL@V!.[OZ>("\`!"QL@V!.[OZV3OH``DSOJ
M``,`!"QL@V!.[O\Z3OH``B)O``0L;(-@3N[^VBQL@V!.[O]\3OH``B)O``0@6
M+P`(+&R#8$[N_RX@+P`$+&R#8$[N_K!.^@`"(&\`!"QL@V!.[OZ,(&\`!""(L
M6)!"J``$(4@`"$YU(&\`!$SO`@$`""(O`!`L;(-@3N[^1"QL@V`B;P`$("\`<
M"$[N_=@B;P`$+&R#8$[N_I@B;P`$+&R#8$[N_H9,[P`#``0L;(-@3N[^SB)OA
M``0L;(-@3N[^)B!O``0L;(-@3N[^@$SO`P``!"QL@[9.[O^@(&\`!"QL@[9.'
M[O^F(&\`!"QL@[9.[O^R``````/L`````0````$```KL`````````_(```/JM
M````U0!:?UH`IH&F```````````````%```$K```!*\```2T```$N0``!+T`S
M``2_```$Q```!,@```3-```$T```!-4```39```$W@``!.$```3D```$Z```-
M!.T```3R```$]@``!/H```3\```%````!04```4)```%#@``!1,```48```%)
M'@``!20```4J```%,```!38```4\```%0@``!4@```5.```%5```!5L```5BN
M```%:0``!7````5W```%?0``!80```6+```%D@````!R``````!R*P````)W9
M`````P%W*P```P)A````"0%A*P``"0)X````!0%X*P``!0(````````P,3(S;
M-#4V-S@Y86)C9&5F````("`@("`@("`@,#`P,#`@("`@("`@("`@("`@("`@L
M(""00$!`0$!`0$!`0$!`0$!`#`P,#`P,#`P,#$!`0$!`0$`)"0D)"0D!`0$!"
M`0$!`0$!`0$!`0$!`0$!`4!`0$!`0`H*"@H*"@("`@("`@("`@("`@("`@("N
M`@("0$!`0"```````````````````0`````!``````````````````````$!J
M`````0`````````````````````!`@````$`````````````````````````%
M`````````````````````````````````````````````````````````````
M`````````````````````````````````````````````````````````````
M`````````````````````````````````````````````````````````````
M`````````````````````````````````````````````````````````````
M`````````````````````````````````````````````````````````````
M`````````````````````````````````````````````````````````````
M`````````````````````````````````````````````````````````````
M`````````````````````````````````````````````````````````````
M%````^P````N`````````!0````8````'````"`````D````*````"P````P!
M````-````#@````\````0````$0```!(````3````%````!4````6````%P`8
M``!@````9````&@```!L````<````'0```!X````?````(````"$````B```\
M`(P```"0````E````)@```"<````H````*0```"H````K````+````"T````@
EN````+P```#`````Q````,@````````#\@```^L````!```#\K``)
``
end
size 8992
SHAR_EOF
# End of shell archive
exit 0
--
Bob Page, U of Lowell CS Dept. page@swan.ulowell.edu ulowell!page
Have five nice days.